# -*- coding: utf-8 -*-
# @Time    : 2020/10/22 13:52
# @Author  : Leo
# @FileName: wechat_request.py
# @Software: PyCharm

import requests
import json
from modules.user.user_manage import UserManager
import xml.sax
import xml.sax.handler
from utils import global_info

class XMLHandler(xml.sax.handler.ContentHandler):
    def __init__(self):
        self.buffer = ""
        self.mapping = {}

    def startElement(self, name, attributes):
        self.buffer = ""

    def characters(self, data):
        self.buffer += data

    def endElement(self, name):
        self.mapping[name] = self.buffer

    def getDict(self):
        return self.mapping

    def xmlToDict(self, data):
        '''
        xml字符串转dict
        @param data:xml格式的字符串
        @return: 字典
        '''

        xml.sax.parseString(data, self)
        ret = self.getDict()
        return  ret



class WechatRequest():
    #  微信开发者配置相关
    AppID = global_info.WECHAT_APP_ID
    AppSecret = global_info.WECHAT_APP_SECRET


    # 主动消息
    WechatHelloMessage = 'Hi，欢迎关注AnyHungry平台服务号!'
    HelloMessage = "Hi，您已成功绑定AnyHungry平台服务号！可实时接收AnyHungry账户(用户名：test_user)的告警信息"
    ByeByeMessage = "Hi，您已成功绑定AnyHungry平台服务号！将不再接收AnyHungry账户(用户名：test_user)的告警信息"
    # UserNotExistsMessage = "您扫描的二维码无效，不存在该用户，绑定失败！"


    @classmethod
    def getAccessToken(cls):
        '''
        获取微信公众号请求token(有效期两个小时，唯一标识公众号)，用于发起请求
        @return: token:str
        '''
        url = 'https://api.weixin.qq.com/cgi-bin/token?'
        parpams = {'grant_type':'client_credential',\
                   'appid':cls.AppID,
                   'secret':cls.AppSecret}
        response = requests.get(url=url, params=parpams)
        data = json.loads(response.content)
        # print(data)
        accessToken = data['access_token']
        return  accessToken
    @classmethod
    def getQR(cls, uuid):
        '''
        获取二维码(用户扫描关注公众号)
        @param uuid: 携带的场景值，可以是任意字符串
        @return:二维码url地址
        '''
        acces_token = cls.getAccessToken()
        url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='+acces_token
        data = {"expire_seconds": 1800,  # 有效期，单位是秒
                "action_name": "QR_STR_SCENE",
                "action_info": {"scene":
                                    {"scene_str": uuid}
                                }
                }
        response = requests.post(url, json.dumps(data))
        data_dict = json.loads(response.content)
        return 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='+data_dict['ticket']

    @classmethod
    def getUserList(cls):
        '''
        # 获取公众号微信用户列表(openid列表)
        @return:openid列表:list
        '''

        ACCESS_TOKEN = cls.getAccessToken()
        url = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s' % ACCESS_TOKEN
        response = requests.get(url)
        data = json.loads(response.content)
        openid_list = data['data']['openid']
        return openid_list

    @classmethod
    def sendMessage(cls, openid, content):
        '''
        主动向指定用户发送文本消息(客服消息接口)
        @param openid: 指定的用户  byte_string
        @param content: 发送的内容  byte_string
        @return:
        '''
        # if isinstance(openid, unicode):
        #     openid = openid.encode('utf-8')
        # if isinstance(content, unicode):
        #     content = content.encode('utf-8')
        ACCESS_TOKEN = cls.getAccessToken()
        url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s' % (ACCESS_TOKEN)
        data = {
            "touser": openid,
            "msgtype": "text",
            "text":
                {
                    "content": content
                }
        }
        response = requests.post(url, json.dumps(data, ensure_ascii=False).encode('utf-8'))
        # print(response.content)

        return response.status_code

    @classmethod
    def response_wechat_event(cls, data):
        '''
        处理微信事件转发post请求
        @param data: 请求body
        @return:
        '''
        # print  data
        # 回复用户消息
        if 'Event' not in data.keys():
            return  cls.sendMessage(openid=data['FromUserName'], content='欢迎关注!')
        # 处理微信事件推送
        else:
            event, from_user = data['Event'], data['FromUserName']  # 推送事件类型  来自的用户openid
            eventKey = data['EventKey']     # 二维码的场景值 可携带uid
            if event == 'subscribe' and eventKey == '':  # 不通过扫描绑定二维码进入服务号并关注
                return cls.sendMessage(openid=from_user,
                                           content=cls.WechatHelloMessage)  # 向关注的用户发送欢迎信息

            # 处理扫描带场景值得二维码事件
            user_id = eventKey.split('_')[-1]  # 用户id
            if event == 'subscribe' or event == 'SCAN':  # 关注-发送欢迎信息-进行绑定操作-发送绑定信息    扫描-进行绑定操作-发送绑定信息
                if event == 'subscribe':
                    cls.sendMessage(openid=from_user,
                                               content=cls.WechatHelloMessage)  # 向关注的用户发送欢迎信息
                # 用户表绑定wechat
                if UserManager().is_exists_by_userId(user_id=user_id):
                    user_info = UserManager().get_by_userId(user_id=user_id)[0]  # 查询用户信息
                    loginName = user_info['name']  # 用户显示名（用于发送欢迎信息）
                    # 更改用户的wechat_id
                    UserManager().update(user_info={'wechat_id': from_user, 'name':loginName})
                    cls.sendMessage(openid=from_user,
                                    content=cls.HelloMessage.replace('test_user', loginName))  # 向关注的用户发送绑定成功
                    return 200
            elif event == 'unsubscribe':  # 取关  解绑
                pass
                return 200

